package com.adjy.pathbuilders.scenario.internal;

import static com.adjy.pathbuilders.commons.Preconditions.checkNotNull;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import android.util.Log;

import com.adjy.pathbuilders.commons.InvalidSourceException;
import com.adjy.pathbuilders.scenario.Scenario;
import com.adjy.pathbuilders.scenario.ScenarioLoader;
import com.adjy.pathbuilders.scenario.ScenarioObject;

/**
 * An implementation of a {@link ScenarioLoader} that supports reading  
 * from streams with comments.
 */
public class DefaultScenarioLoader implements ScenarioLoader {

	@Override
	public Scenario load(InputStream sourceStream) throws IOException {
		checkNotNull(sourceStream, "sourceStream must not be null.");
		return new DefaultScenario(tryGetScenarioObjects(new BufferedReader(new InputStreamReader(sourceStream))));
	}
	
	private List<ScenarioObject> tryGetScenarioObjects(BufferedReader reader) throws IOException {
		try {
			return getScenarioObjects(reader);
		} catch (InvalidSourceException e) {
			throw new IOException("Not able to load a scenario from the file.");
		} finally {
			reader.close();
		}
	}
	
	private List<ScenarioObject> getScenarioObjects(BufferedReader reader)
			throws IOException, InvalidSourceException {
		List<ScenarioObject> scenarioObjects = new ArrayList<ScenarioObject>();
		String line = nextNotCommentLine(reader);

		while (line != null) {
			ScenarioObject newObject = DefaultScenarioObject.load(line);
			scenarioObjects.add(newObject);
			line = nextNotCommentLine(reader);
		}
		
		return scenarioObjects;
	}

	private String nextNotCommentLine(BufferedReader reader) throws IOException {
		String line = null;
		do {
			line = reader.readLine();
		}
		while (line != null && lineIsAComment(line));
		
		return line;
	}
	
	private boolean lineIsAComment(String line) {
		return line.equals("") || line.startsWith("#");
	}

	@Override
	public Scenario load(List<String> source) {
		checkNotNull(source, "source must not be null.");
		List<ScenarioObject> scenarioObjects = new ArrayList<ScenarioObject>();
		
		for (String string : source) {
			try {
				scenarioObjects.add(DefaultScenarioObject.load(string));
			} catch (InvalidSourceException e) {
				throw new IllegalArgumentException("Not able to load a scenario.");
			}
		}
		return new DefaultScenario(scenarioObjects);
	}
	
	public List<ScenarioDescription> getScenarioDescriptions(InputStream sourceStream) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(sourceStream));
		List<ScenarioDescription> descriptions = new ArrayList<ScenarioDescription>();
		String line = nextNotCommentLine(reader);

		while (line != null) {
			System.out.println("line: " + line);
			ScenarioDescription newObject = ScenarioDescription.load(line);
			
			if (newObject != null) {
				descriptions.add(newObject);
			} else {
				Log.e("getScenarioDescriptions", "Invalid Line: " + line);
			}
			line = nextNotCommentLine(reader);
		}
		
		return descriptions;
	}
}
